/** 
 * Project Name:tinysql 
 * File Name:PlusSqlScriptUtil.java 
 * Package Name:com.wdy.golden.tinysql.plus.util 
 * Date:2021年4月26日下午9:52:23 
 * 
*/  
package com.wdy.golden.tinysql.plus.util;

import java.lang.reflect.Method;
import java.util.Map;

import com.wdy.golden.tinysql.constant.TinysqlConstants;
import com.wdy.golden.tinysql.mapping.SqlScript;
import com.wdy.golden.tinysql.plus.ConditionSymbol;
import com.wdy.golden.tinysql.plus.annotation.TinyBuilderOperation;
import com.wdy.golden.tinysql.plus.annotation.TinyCommonOperation;
import com.wdy.golden.tinysql.plus.builder.SqlBuilder;
import com.wdy.golden.tinysql.plus.builder.TinySqlBuilderMethod;
import com.wdy.golden.tinysql.plus.common.ITinysqlPlus;
import com.wdy.golden.tinysql.plus.common.TinysqlPlusMethod;
import com.wdy.golden.tinysql.util.StringUtil;
import com.wdy.golden.tinysql.util.TinysqlUtil;

/** 
 * ClassName:PlusSqlScriptUtil <br/> 
 * Function: TODO ADD FUNCTION. <br/> 
 * Reason:   TODO ADD REASON. <br/> 
 * Date:     2021年4月26日 下午9:52:23 <br/> 
 * @author   DongYe_Wu 
 * @version
 * @see       
 */
public class PlusSqlScriptUtil {
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static SqlScript getSqlScript(Class<?> interfaceType,Method method, Object[] args, Map<String, Object> argMap) {
		SqlScript sqlScript = new SqlScript();
		String originSql = null;
		String paginationSql = null;
		String countSql = null;

		if(method.isAnnotationPresent(TinyCommonOperation.class)) {
			TinyCommonOperation tinyCommonOperation = method.getAnnotation(TinyCommonOperation.class);
			
			if(StringUtil.equals(tinyCommonOperation.name(), TinysqlPlusMethod.tinyInsert.name())) {
				SqlBuilder<?> sqlBuilder = new SqlBuilder(args[0]);
				originSql = sqlBuilder.insert().buildSql();
			}
			else if(StringUtil.equals(tinyCommonOperation.name(), TinysqlPlusMethod.tinyDeleteById.name())){
				Class<?> clazz = PlusClassUtil.getInterfaceGenericClass(interfaceType, ITinysqlPlus.class);
				SqlBuilder<?> sqlBuilder = new SqlBuilder(clazz);
				originSql = sqlBuilder.delete().from().where()
						.condition(
							PlusClassUtil.getIdFieldName(clazz),
							ConditionSymbol.EQ
						).buildSql();
			}
			else if(StringUtil.equals(tinyCommonOperation.name(), TinysqlPlusMethod.tinyDeleteByIds.name())){
				Class<?> clazz = PlusClassUtil.getInterfaceGenericClass(interfaceType, ITinysqlPlus.class);
				SqlBuilder<?> sqlBuilder = new SqlBuilder(clazz);
				originSql = sqlBuilder.delete().from().where()
						.condition(
							PlusClassUtil.getIdFieldName(clazz), 
							ConditionSymbol.IN
						).buildSql();
			}
			else if(StringUtil.equals(tinyCommonOperation.name(), TinysqlPlusMethod.tinySelectById.name())){
				Class<?> clazz = PlusClassUtil.getInterfaceGenericClass(interfaceType, ITinysqlPlus.class);
				SqlBuilder<?> sqlBuilder = new SqlBuilder(clazz);
				originSql = sqlBuilder.selectAll().from().where()
						.condition(
							PlusClassUtil.getIdFieldName(clazz),
							ConditionSymbol.EQ
						).buildSql();
			}
			else if(StringUtil.equals(tinyCommonOperation.name(), TinysqlPlusMethod.tinySelectByIds.name())){
				Class<?> clazz = PlusClassUtil.getInterfaceGenericClass(interfaceType, ITinysqlPlus.class);
				SqlBuilder<?> sqlBuilder = new SqlBuilder(clazz);
				originSql = sqlBuilder.selectAll().from().where()
						.condition(
							PlusClassUtil.getIdFieldName(clazz),
							ConditionSymbol.IN
						).buildSql();
			}
			else if(StringUtil.equals(tinyCommonOperation.name(), TinysqlPlusMethod.tinyUpdateById.name())){
				SqlBuilder<?> sqlBuilder = new SqlBuilder(args[0]);
				originSql = sqlBuilder.updateAll().where()
						.condition(
								PlusClassUtil.getIdFieldName(args[0].getClass()), 
								ConditionSymbol.EQ
						).buildSql();
			}
			else if(StringUtil.equals(tinyCommonOperation.name(), TinysqlPlusMethod.tinyUpdateByIds.name())){
				SqlBuilder<?> sqlBuilder = new SqlBuilder(args[0]);
				originSql = sqlBuilder.updateAll().where()
						.condition(
								PlusClassUtil.getIdFieldName(args[0].getClass()), 
								ConditionSymbol.IN
						).buildSql();
			}
		}else if(method.isAnnotationPresent(TinyBuilderOperation.class)) {
			TinyBuilderOperation tinyBuilderOperation = method.getAnnotation(TinyBuilderOperation.class);
			SqlBuilder<?> builder = (SqlBuilder<?>)args[0];
			originSql = builder.buildSql();
			//pagination
			if(StringUtil.equals(tinyBuilderOperation.name(), TinySqlBuilderMethod.selectPage.name())) {
				String rowStartParam = builder.getRowStartParam();
				if(StringUtil.isEmpty(rowStartParam)) {
					rowStartParam = TinysqlConstants.DEFAULT_PAGINATION_ROWSTART;
				}
				String rowEndParam = builder.getRowEndParam();
				if(StringUtil.isEmpty(rowEndParam)) {
					rowEndParam = TinysqlConstants.DEFAULT_PAGINATION_ROWEND;
				}
				int rowEnd = (int)argMap.get(rowStartParam);
				int rowStart = (int)argMap.get(rowEndParam);
				paginationSql = TinysqlUtil.getPaginationSql(originSql, rowEnd, rowStart);
				countSql = TinysqlUtil.getCountSql(originSql);
				sqlScript.setPaginationSql(paginationSql);
				sqlScript.setCountSql(countSql);
				sqlScript.setSuperPagination(true);
			}
			//second cache
			if(
					StringUtil.equals(tinyBuilderOperation.name(), TinySqlBuilderMethod.selectOne.name())
					|| StringUtil.equals(tinyBuilderOperation.name(), TinySqlBuilderMethod.select.name())
					|| StringUtil.equals(tinyBuilderOperation.name(), TinySqlBuilderMethod.selectPage.name())
			) {
				if(builder.isSecondCache()) {
					sqlScript.setSecondCache(true);
					sqlScript.setCacheSeconds(builder.getCacheSeconds());
				}else {
					sqlScript.setSecondCache(false);
					sqlScript.setCacheSeconds(0);
				}
			}
		}
		
		sqlScript.setOriginSql(originSql);
		
		return sqlScript;
	}

}
